<?php declare(strict_types=1);

namespace Zyucv7\Core\Web;

use Zyucv7\Core\Web\Exceptions\SessionException;

/**
 * 企业级多应用会话管理类
 */
class Session
{

    /**
     * 当前处理驱动
     * 
     * @var object
     */
    private $handler;

    /**
     * Session 配置参数
     * 
     * @var array
     */
    private $config = [
        'handler' => 'file',        // 存储方式：file, redis, memcached, database
        'lifetime' => 604800,       // 默认是一周
        'save_path' => '',      // Session文件保存路径
        'file_prefix' => 'sys_sess_', // 文件存储前缀
        'session_key' => ''
    ];

    /**
     * 构造函数
     * 
     * @param array $config 配置参数
     */
    public function __construct($config = [])
    {
        // 合并配置
        $this->config = array_merge($this->config, $config);

        if(empty($this->config['save_path'])) {
            $this->config['save_path'] = v7_get_session_path();
        }
        
        // 查找驱动
        $handlerClass = __NAMESPACE__ . '\\Session\\' . ucfirst($this->config['handler']) . 'Handler';
        if (!class_exists($handlerClass)) {
            throw SessionException::InvalidArgument("Session handler class not found: {$handlerClass}");
        }

        // 实例化驱动
        $this->handler = new $handlerClass($this->config);
    }

    /**
     * Session启动
     */
    public function start(): void
    {
        $this->handler->start();
    }

    /**
     * 检查Session是否已启动
     * 
     * @return bool
     */
    public function isStarted(): bool
    {
        return $this->handler->isStarted();
    }
    
    /**
     * 设置Session变量
     * 
     * @param string $key
     * @param mixed $value
     * @return void
     * @throws RuntimeException 如果Session未启动
     */
    public function set(string $key, $value): void
    {
        $this->handler->set($key, $value);
    }
    
    /**
     * 获取Session变量
     * 
     * @param string $key
     * @param mixed $default
     * @throws RuntimeException 如果Session未启动
     */
    public function get(string $key, $default = null)
    {
        return $this->handler->get($key, $default);
    }
    
    /**
     * 删除Session变量
     * 
     * @param string $key
     * @return bool
     * @throws RuntimeException 如果Session未启动
     */
    public function remove(string $key): bool
    {
        return $this->handler->remove($key);
    }
    
    /**
     * 清空所有Session变量（但保持Session ID）
     * 
     * @return void
     * @throws RuntimeException 如果Session未启动
     */
    public function clear(): void
    {
        $this->handler->clear();
    }
    
    /**
     * 销毁Session（包括Session ID）
     * 
     * @return void
     * @throws RuntimeException 如果Session未启动
     */
    public function destroy(): void
    {
        $this->handler->clear();
    }

    /**
     * 设置Session ID
     * 
     * @param string $id
     * @return void
     */
    public function setId(string $id): void
    {
        $this->handler->setId($id);
    }
    
    /**
     * 获取Session ID
     * 
     * @return string
     */
    public function getId(): string
    {
        return $this->handler->getId();
    }
    
    /**
     * 获取所有Session数据
     * 
     * @return array
     * @throws RuntimeException 如果Session未启动
     */
    public function all(): array
    {
        return $this->handler->all();
    }
    
    /**
     * 设置Flash消息（一次性消息）
     * 
     * @param string $key
     * @param mixed $value
     * @return void
     */
    public function setFlash(string $key, $value): void
    {
        $this->handler->set("_flash_{$key}", $value);
    }
    
    /**
     * 获取并清除Flash消息
     * 
     * @param string $key
     * @param mixed $default
     * @return mixed
     */
    public function getFlash(string $key, $default = null)
    {
        $flashKey = "_flash_{$key}";
        $value = $this->handler->get($flashKey, $default);
        $this->handler->remove($flashKey);
        return $value;
    }
    
    /**
     * 检查Session是否已过期
     * 
     * @return bool
     */
    public function isExpired(): bool
    {
        return $this->handler->isExpired();
    }
}